﻿using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Linq;
using Omu.Awesome.Core;
using XPressify.Core;
using XPressify.Data.Helpers;

namespace XPressify.Data.CompliedQueries
{
    public class EventCompiledQueries
    {
        

        public static Func<Repository, Guid, Event> GetEvent
        {
            get
            {
                return CompiledQuery.Compile<Repository, Guid, Event>(
                    (context, id) => context.BaseSubjects.OfType<Event>().SingleOrDefault(ev => ev.Id == id)
                    );
            }
        }

        public static Func<Repository, Guid, bool> IsEvent
        {
            get
            {
                return CompiledQuery.Compile<Repository, Guid, bool>(
                    (context, id) => context.BaseSubjects.OfType<Event>().Any(ev => ev.Id == id)
                    );
            }
        }

        public static Func<Repository, Guid, IEnumerable<Event>> GetEventsOfDesc
        {
            get
            {
                return CompiledQuery.Compile<Repository, Guid, IEnumerable<Event>>(
                    (context, userId) => context.BaseObjects.OfType<Relationship>().Where(
                        x => x.BaseSubjectId == userId && x.Status == RelationshipStatus.Confirmed).Select(
                        x => x.BaseSubject2).OfType<Event>().OrderByDescending(x => x.StartDate)
                    );
            }
        }

        public static Func<Repository, Guid, IEnumerable<Event>> GetPublicEventsOfDesc
        {
            get
            {
                return CompiledQuery.Compile<Repository, Guid, IEnumerable<Event>>(
                    (context, userId) => context.BaseObjects.OfType<Relationship>().Where(
                    x => x.BaseSubjectId == userId && x.Status == RelationshipStatus.Confirmed).Select(
                        x => x.BaseSubject2).OfType<Event>().Where(x => x.PrivacyType == SubjectPrivacy.Public).
                        OrderByDescending(x => x.StartDate)
                    );
            }
        }

        public static Func<Repository, Guid, Guid, bool> IsMemberOf
        {
            get
            {
                return CompiledQuery.Compile<Repository, Guid, Guid, bool>(
                    (context, userId, eventId) => context.BaseObjects.OfType<Relationship>().Any(
                        rel =>
                        rel.BaseSubject.Id == userId && rel.BaseSubject2.Id == eventId &&
                        rel.RelationType == RelationshipType.MemberOf && rel.Status == RelationshipStatus.Confirmed)
                    );
            }
        }

        public static Func<Repository, Guid, Guid, bool> IsAdminBlocked
        {
            get
            {
                return CompiledQuery.Compile<Repository, Guid, Guid, bool>(
                    (context, userId, adminId) => context.BaseObjects.OfType<Relationship>().Any(
                    rel =>
                    ((rel.BaseSubject.Id == userId && rel.BaseSubject2.Id == adminId) ||
                     (rel.BaseSubject2.Id == userId && rel.BaseSubject.Id == adminId)) &&
                    rel.RelationType == RelationshipType.FriendOf && rel.Status == RelationshipStatus.Blocked)
                    );
            }
        }

    }
}